<template>
  <view class="video-player-container" :class="{ fullscreen: isFullscreen }">
    <video
      id="myVideo"
      ref="videoRef"
      class="video-element"
      :src="src"
      :poster="poster"
      :controls="false"
      :loop="loop"
      :muted="muted"
      :show-center-play-btn="false"
      :enable-progress-gesture="true"
      :object-fit="objectFit"
      :initial-time="0"
      :direction="0"
      :show-fullscreen-btn="false"
      :show-play-btn="false"
      :show-progress="false"
      @timeupdate="onTimeUpdate"
      @ended="onEnded"
      @play="onPlay"
      @pause="onPause"
      @waiting="onWaiting"
      @error="onError"
      @loadedmetadata="onLoadedMetadata"
    ></video>

    <!-- 自定义控制层 -->
    <view
      class="video-controls"
      :class="{ 'controls-visible': controlsVisible || isPaused }"
      @mousemove="showControls"
      @mouseleave="controlsVisible = false"
      @touchstart="showControls"
      @touchend="controlsVisible = false"
    >
      <!-- 加载动画 -->
      <!-- <view class="loading-spinner" v-if="isLoading">
        <view class="spinner"></view>
      </view> -->
      <!-- 中央播放/暂停按钮 -->
      <view class="center-control">
        <view
          class="play-button"
          :class="{ 'is-playing': !isPaused }"
          @click.stop="togglePlay"
        >
          <view class="icon-play" v-if="isPaused">▶</view>
          <view class="icon-pause" v-else>⏸</view>
        </view>
      </view>

      <!-- 底部控制栏 -->
      <view class="bottom-controls">
        <!-- 进度条 -->
        <view
          class="progress-bar"
          @click.stop="onProgressClick"
          @touchstart.stop="onDragStart"
          @mousedown.stop="onDragStart"
        >
          <view class="progress-background"></view>
          <view
            class="progress-current"
            :style="{ width: `${(currentTime / duration) * 100}%` }"
          ></view>
          <view
            class="progress-handle"
            :style="{ left: `${(currentTime / duration) * 100}%` }"
          ></view>
        </view>

        <!-- 时间显示 -->
        <view class="time-display">
          <text>{{ formatTime(currentTime) }}</text>
          <text> / </text>
          <text>{{ formatTime(duration) }}</text>
        </view>

        <!-- 右侧控制按钮 -->
        <view class="right-controls">
          <!-- 音量控制 -->
          <view class="volume-control" @click.stop="toggleMute">
            <view class="icon-volume" v-if="!muted">🔊</view>
            <view class="icon-mute" v-else>🔇</view>
          </view>

          <!-- 全屏按钮 -->
          <view class="fullscreen-control" @click.stop="toggleFullscreen">
            <view class="icon-fullscreen" v-if="!isFullscreen">⛶</view>
            <view class="icon-exit-fullscreen" v-else>⛶</view>
          </view>
        </view>
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from "vue";

interface Props {
  src: string;
  poster?: string;
  loop?: boolean;
  muted?: boolean;
  autoplay?: boolean;
  objectFit?: "contain" | "fill" | "cover";
}

const props = withDefaults(defineProps<Props>(), {
  poster: "",
  loop: false,
  muted: false,
  autoplay: false,
  objectFit: "contain",
});

const emit = defineEmits<{
  (e: "play"): void;
  (e: "pause"): void;
  (e: "ended"): void;
  (e: "timeupdate", time: number): void;
  (e: "error", error: any): void;
}>();

// 状态变量
const videoRef = ref<any>(null);
const isPaused = ref(true);
const isLoading = ref(false);
const isFullscreen = ref(false);
const controlsVisible = ref(true);
const currentTime = ref(0);
const duration = ref(0);
const muted = ref(props.muted);
const isDragging = ref(false);
const wasPlayingBeforeDrag = ref(false);

// 控制栏自动隐藏
let controlsTimer: number | null = null;

const showControls = () => {
  controlsVisible.value = true;
  if (controlsTimer) clearTimeout(controlsTimer);
  if (!isPaused.value) {
    controlsTimer = setTimeout(() => {
      controlsVisible.value = false;
    }, 3000);
  }
};

const toggleControls = () => {
  if (controlsVisible.value) {
    controlsVisible.value = false;
  } else {
    showControls();
  }
};

// 播放控制
const togglePlay = async () => {
  try {
    const video = uni.createVideoContext("myVideo");
    if (isPaused.value) {
      video.play();
    } else {
      video.pause();
    }
  } catch (error) {
    console.error("播放控制失败:", error);
  }
};

// 音量控制
const toggleMute = () => {
  muted.value = !muted.value;
  if (videoRef.value) {
    videoRef.value.muted = muted.value;
  }
};

// 全屏控制
const toggleFullscreen = () => {
  const video = uni.createVideoContext("myVideo");
  if (!isFullscreen.value) {
    video.requestFullScreen();
  } else {
    video.exitFullScreen();
  }
  isFullscreen.value = !isFullscreen.value;

  // 在状态改变后重新初始化视频
  setTimeout(() => {
    const newVideo = uni.createVideoContext("myVideo");
    if (!isPaused.value) {
      newVideo.play();
    }
  }, 300);
};

// 监听全屏状态变化
uni.onWindowResize(() => {
  const info = uni.getSystemInfoSync();
  const isCurrentlyFullscreen = info.windowWidth > info.windowHeight;
  if (isFullscreen.value !== isCurrentlyFullscreen) {
    isFullscreen.value = isCurrentlyFullscreen;
    // 在状态改变后重新初始化视频
    setTimeout(() => {
      const video = uni.createVideoContext("myVideo");
      if (!isPaused.value) {
        video.play();
      }
    }, 300);
  }
});

// 进度条控制
const onProgressClick = (event: any) => {
  if (isDragging.value) return;

  const query = uni.createSelectorQuery();
  query
    .select(".progress-bar")
    .boundingClientRect((data) => {
      if (data) {
        const ratio = (event.detail.x - data.left) / data.width;
        const newTime = ratio * duration.value;
        const wasPlaying = !isPaused.value;

        const video = uni.createVideoContext("myVideo");
        video.seek(newTime);
        currentTime.value = newTime;

        // 确保视频可以继续播放
        if (wasPlaying || currentTime.value < duration.value) {
          setTimeout(() => {
            video.play();
            isPaused.value = false;
          }, 100);
        }
      }
    })
    .exec();
};

// 拖拽进度条控制
const onDragStart = (event: any) => {
  // 记录拖拽开始前的播放状态
  wasPlayingBeforeDrag.value = !isPaused.value;
  isDragging.value = true;

  // 暂停视频
  const video = uni.createVideoContext("myVideo");
  video.pause();
  isPaused.value = true;

  // 显示控制栏
  showControls();

  // 添加移动和结束事件监听
  document.addEventListener("mousemove", onDragMove);
  document.addEventListener("touchmove", onDragMove);
  document.addEventListener("mouseup", onDragEnd);
  document.addEventListener("touchend", onDragEnd);
};

const onDragMove = (event: any) => {
  if (!isDragging.value) return;

  // 阻止默认行为和事件冒泡
  event.preventDefault?.();

  const query = uni.createSelectorQuery();
  query
    .select(".progress-bar")
    .boundingClientRect((data) => {
      if (data) {
        // 获取鼠标或触摸位置
        const clientX =
          event.clientX ||
          (event.touches && event.touches[0] ? event.touches[0].clientX : 0);

        // 计算新的播放位置
        let ratio = (clientX - data.left) / data.width;
        ratio = Math.max(0, Math.min(1, ratio)); // 确保比例在0-1之间

        const newTime = ratio * duration.value;
        currentTime.value = newTime;

        // 实时预览（可选，根据性能考虑是否启用）
        const video = uni.createVideoContext("myVideo");
        video.seek(newTime);
      }
    })
    .exec();
};

const onDragEnd = (event: any) => {
  if (!isDragging.value) return;

  // 移除事件监听
  document.removeEventListener("mousemove", onDragMove);
  document.removeEventListener("touchmove", onDragMove);
  document.removeEventListener("mouseup", onDragEnd);
  document.removeEventListener("touchend", onDragEnd);

  // 设置最终位置
  const video = uni.createVideoContext("myVideo");
  video.seek(currentTime.value);

  // 如果之前是播放状态，则继续播放
  if (wasPlayingBeforeDrag.value) {
    setTimeout(() => {
      video.play();
      isPaused.value = false;
    }, 100);
  }

  isDragging.value = false;
};

// 事件处理
const onTimeUpdate = (event: any) => {
  currentTime.value = event.detail.currentTime;
  emit("timeupdate", currentTime.value);
};

const onLoadedMetadata = (event: any) => {
  duration.value = event.detail.duration;
};

const onPlay = () => {
  isPaused.value = false;
  showControls();
  emit("play");
};

const onPause = () => {
  isPaused.value = true;
  showControls();
  emit("pause");
};

const onEnded = () => {
  isPaused.value = true;
  showControls();
  emit("ended");
  // 重置视频到开始位置
  const video = uni.createVideoContext("myVideo");
  video.seek(0);
  currentTime.value = 0;
};

const onWaiting = () => {
  isLoading.value = true;
};

const onError = (error: any) => {
  console.error("视频播放错误:", error);
  emit("error", error);
};

// 工具函数
const formatTime = (seconds: number) => {
  const minutes = Math.floor(seconds / 60);
  const remainingSeconds = Math.floor(seconds % 60);
  return `${minutes.toString().padStart(2, "0")}:${remainingSeconds
    .toString()
    .padStart(2, "0")}`;
};

onMounted(() => {
  if (props.autoplay) {
    togglePlay();
  }
});

onUnmounted(() => {
  if (controlsTimer) {
    clearTimeout(controlsTimer);
  }
});
</script>

<style lang="scss">
.video-player-container {
  position: relative;
  width: 100%;
  height: 0;
  padding-bottom: 56.25%;
  /* 16:9 宽高比 */
  background-color: #000;
  overflow: hidden;

  &.fullscreen {
    padding-bottom: 100vh;
  }

  .video-element {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
  }

  .video-controls {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: linear-gradient(
      to bottom,
      rgba(0, 0, 0, 0.3) 0%,
      transparent 30%,
      transparent 70%,
      rgba(0, 0, 0, 0.3) 100%
    );
    opacity: 0;
    transition: opacity 0.3s ease;

    &.controls-visible {
      opacity: 1;
    }

    .loading-spinner {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);

      .spinner {
        width: 40px;
        height: 40px;
        border: 4px solid rgba(255, 255, 255, 0.3);
        border-top-color: #fff;
        border-radius: 50%;
        animation: spin 1s linear infinite;
      }
    }

    .center-control {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      z-index: 2;

      .play-button {
        width: 80rpx;
        height: 80rpx;
        background: rgba(0, 0, 0, 0.6);
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
        transition: all 0.3s ease;

        &:active {
          transform: scale(0.95);
        }

        .icon-play,
        .icon-pause {
          color: #fff;
          font-size: 40rpx;
        }
      }
    }

    .bottom-controls {
      position: absolute;
      left: 0;
      right: 0;
      bottom: 0;
      padding: 15rpx 10rpx 5rpx 15rpx;
      display: flex;
      align-items: center;
      gap: 20rpx;

      .progress-bar {
        flex: 1;
        height: 4px;
        background: rgba(255, 255, 255, 0.3);
        position: relative;
        cursor: pointer;

        .progress-background {
          position: absolute;
          width: 100%;
          height: 100%;
          background: rgba(255, 255, 255, 0.3);
        }

        .progress-current {
          position: absolute;
          height: 100%;
          background: #ff0000;
          transition: width 0.1s linear;
        }

        .progress-handle {
          position: absolute;
          top: 50%;
          width: 12px;
          height: 12px;
          background: #ff0000;
          border-radius: 50%;
          transform: translate(-50%, -50%);
          transition: left 0.1s linear;
          z-index: 10;
          cursor: grab;

          &:active {
            cursor: grabbing;
            transform: translate(-50%, -50%) scale(1.2);
          }
        }
      }

      .time-display {
        font-size: 24rpx;
        color: #fff;
        text-shadow: 0 0 2px rgba(0, 0, 0, 0.5);
      }

      .right-controls {
        display: flex;
        gap: 20rpx;

        .volume-control,
        .fullscreen-control {
          width: 40rpx;
          height: 40rpx;
          display: flex;
          align-items: center;
          justify-content: center;
          cursor: pointer;
          color: #fff;
          font-size: 24rpx;

          &:active {
            transform: scale(0.95);
          }
        }
      }
    }
  }
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
</style>
